#ifndef QCPU_H
#define QCPU_H

#include <QObject>
#include <QList>
#include <QString>
#include "QMemoryDevice.h"
#include "QInstruction.h"

class QCPU : public QObject
{
    Q_OBJECT
public:

    enum CPUtype{
        MCS51 = 1,
        AVR = 2,
        PIC = 3,
        ARM = 4
    };

    enum MCS51_SFR{
        B = 0xF0,
        ACC = 0xE0,
        PSW = 0xD0,
        IP = 0xB8,
        P3 = 0xB0,
        IE = 0xA8,
        P2 = 0xA0,
        SCON = 0x98,
        P1 = 0x90,
        TCON = 0x88,
        P0 = 0x80,
        SBUF = 0x99,
        TMOD = 0x89,
        SP = 0x81,
        TL0 = 0x8A,
        DPL = 0x82,
        TL1 = 0x8B,
        DPH = 0x83,
        TH0 = 0x8C,
        TH1 = 0x8D,
        PCON = 0x87
    };

    enum REGISTER_BANK{
        BANK0_R0 = 0x00,
        BANK0_R1 = 0x01,
        BANK0_R2 = 0x02,
        BANK0_R3 = 0x03,
        BANK0_R4 = 0x04,
        BANK0_R5 = 0x05,
        BANK0_R6 = 0x06,
        BANK0_R7 = 0x07,

        BANK1_R0 = 0x08,
        BANK1_R1 = 0x09,
        BANK1_R2 = 0x0A,
        BANK1_R3 = 0x0B,
        BANK1_R4 = 0x0C,
        BANK1_R5 = 0x0D,
        BANK1_R6 = 0x0E,
        BANK1_R7 = 0x0F,

        BANK2_R0 = 0x10,
        BANK2_R1 = 0x11,
        BANK2_R2 = 0x12,
        BANK2_R3 = 0x13,
        BANK2_R4 = 0x14,
        BANK2_R5 = 0x15,
        BANK2_R6 = 0x16,
        BANK2_R7 = 0x17,

        BANK3_R0 = 0x18,
        BANK3_R1 = 0x19,
        BANK3_R2 = 0x1A,
        BANK3_R3 = 0x1B,
        BANK3_R4 = 0x1C,
        BANK3_R5 = 0x1D,
        BANK3_R6 = 0x1E,
        BANK3_R7 = 0x1F

    };


    QString mLog;
    CPUtype getCPUtype();
    void setClock(int);
    int getClock();



    unsigned char REGISTER_R0;
    unsigned char REGISTER_R1;
    unsigned char REGISTER_R2;
    unsigned char REGISTER_R3;
    unsigned char REGISTER_R4;
    unsigned char REGISTER_R5;
    unsigned char REGISTER_R6;
    unsigned char REGISTER_R7;

    unsigned short PC;
    unsigned char IR;

    unsigned char *mCodeSpace;
    unsigned char *mDataSpace;
    unsigned char *mIDataSpace;
    unsigned char *mXDataSpace;

//    QMemoryDevice* getMemoryDeivce(int);
    void runInstruction(unsigned char);
    void nextInstruction(int);

    QCPU(CPUtype,int);
    ~QCPU();

private:

    CPUtype mCPUtype;
    int mClock;
    int mNextCycle;

//    QList<QMemoryDevice*> mMemoryList;
//    QList<QInstruction*> mInstructionList;


};

#endif // QCPU_H
